package com.scut.campus.utils;


import cn.hutool.json.JSONObject;
import com.baidubce.qianfan.Qianfan;
import com.baidubce.qianfan.model.image.Image2TextResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.scut.campus.context.BaseContext;
import com.scut.campus.entity.Lost;
import com.scut.campus.entity.Recommend;
import com.scut.campus.entity.Trade;
import com.scut.campus.service.LostService;
import com.scut.campus.service.RecommendService;
import com.scut.campus.service.TradeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.*;

@Component
public class ModelUtil {
    @Autowired
    private LostService lostService;
    @Autowired
    private RecommendService recommendService;
    @Autowired
    private TradeService tradeService;

    private static final String ACCESSKEY="ALTAKZO76jPi3RYIBnFsGzP7dk";
    private static final String SECRETKEY="bbed5e23cdc24c33a94744e424ffd4a8";
    private static final String PROMPT="use three words to describe only one thing in picture and color";
    private static final Double MATCHVAL=0.2;


    public String getImageBase64ByUrl(String imageUrl) {
        try {
            URL url = new URL(imageUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");

            try (InputStream inputStream = conn.getInputStream();
                 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {

                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    byteArrayOutputStream.write(buffer, 0, bytesRead);
                }

                // 将图片数据转换为 Base64 编码
                byte[] imageBytes = byteArrayOutputStream.toByteArray();
                return Base64.getEncoder().encodeToString(imageBytes);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public  String getAuth() {
        // 官网获取的 API Key 更新为你注册的
        String clientId = "jjYSZNXHSeaumYNxPWBDiarJ";
        // 官网获取的 Secret Key 更新为你注册的
        String clientSecret = "ss3kgkqBMajBC9fYZBVIvy6Z5S5xPbd9";
        return getAuth(clientId, clientSecret);
    }

    /**
     * 获取API访问token
     * 该token有一定的有效期，需要自行管理，当失效时需重新获取.
     * @param ak - 百度云官网获取的 API Key
     * @param sk - 百度云官网获取的 Securet Key
     * @return assess_token 示例：
     * "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567"
     */
    public  String getAuth(String ak, String sk) {
        // 获取token地址
        String authHost = "https://aip.baidubce.com/oauth/2.0/token?";
        String getAccessTokenUrl = authHost
                // 1. grant_type为固定参数
                + "grant_type=client_credentials"
                // 2. 官网获取的 API Key
                + "&client_id=" + ak
                // 3. 官网获取的 Secret Key
                + "&client_secret=" + sk;
        try {
            URL realUrl = new URL(getAccessTokenUrl);
            // 打开和URL之间的连接
            HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.err.println(key + "--->" + map.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String result = "";
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
            /**
             * 返回结果示例
             */
            System.err.println("result:" + result);
            JSONObject jsonObject = new JSONObject(result);
            String access_token = (String) jsonObject.get("access_token");
            //String access_token = jsonObject.getString("access_token");
            return access_token;
        } catch (Exception e) {
            System.err.printf("获取token失败！");
            e.printStackTrace(System.err);
        }
        return null;
    }

    public String imgCombination(String picURL) {
        // 请求url
        String url = "https://aip.baidubce.com/api/v1/solution/direct/imagerecognition/combination";
        try {
            Map<String, Object> map = new HashMap<>();
            map.put("imgUrl", picURL);
            List<Object> scenes = new ArrayList<>();
            scenes.add("animal");
            scenes.add("plant");
            scenes.add("ingredient");
            scenes.add("dishs");
            scenes.add("red_wine");
            scenes.add("currency");
            scenes.add("landmark");
            map.put("scenes", scenes);

            String param = GsonUtils.toJson(map);

            // 注意这里仅为了简化编码每一次请求都去获取access_token，线上环境access_token有过期时间， 客户端可自行缓存，过期后重新获取。
            String accessToken = "24.8e9e17634265c0ebecdc39ce6f24e0f1.2592000.1733541335.282335-116146410";

            String result = HttpUtil.post(url, accessToken, "application/json", param);
            System.out.println(result);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public void matchLost(String imageUrl){
        String base64code=this.getImageBase64ByUrl(imageUrl);
        String tag=this.getTag(base64code);

        LambdaQueryWrapper<Lost>lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.select(Lost::getDescription,Lost::getLostId);
        List<Lost>list=lostService.list(lambdaQueryWrapper);

        Map<String,Double>matchvalue=new HashMap<>();

        for(Lost lost:list){
            Double value=this.computeSimilar(lost.getDescription(),tag);
            if(value>=MATCHVAL){
                matchvalue.put(lost.getLostId(),value);
            }
        }


        List<Map.Entry<String, Double>> sortList = new ArrayList<>(matchvalue.entrySet());
        sortList.sort(Map.Entry.comparingByValue(Comparator.reverseOrder()));

        // 使用 LinkedHashMap 保持排序后的顺序
        LinkedHashMap<String, Double> sortedMap = new LinkedHashMap<>();
        for (Map.Entry<String, Double> entry : sortList) {
            sortedMap.put(entry.getKey(), entry.getValue());
        }

        List<String> keys = new ArrayList<>(sortedMap.keySet());
        List<String> firstFiveKeys = keys.size() > 5 ? keys.subList(0, 5) : keys;
        for(String lostId:firstFiveKeys){
            Recommend recommend=new Recommend();
            recommend.setLostId(lostId);
            recommend.setUserId(BaseContext.getCurrentId());
            recommendService.save(recommend);
        }



    }

    public void matchTrade(String imageUrl){
        String base64code=this.getImageBase64ByUrl(imageUrl);
        String tag=this.getTag(base64code);
        //TODO 翻译tag


        LambdaQueryWrapper<Trade>lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.select(Trade::getDescription,Trade::getTradeId);
        List<Trade>list=tradeService.list(lambdaQueryWrapper);

        Map<String,Double>matchvalue=new HashMap<>();

        for(Trade trade:list){
            Double value=this.computeSimilar(trade.getDescription(),tag);
            if(value>=MATCHVAL){
                matchvalue.put(trade.getTradeId(),value);
            }

        }




        List<Map.Entry<String, Double>> sortList = new ArrayList<>(matchvalue.entrySet());
        sortList.sort(Map.Entry.comparingByValue(Comparator.reverseOrder()));

        // 使用 LinkedHashMap 保持排序后的顺序
        LinkedHashMap<String, Double> sortedMap = new LinkedHashMap<>();
        for (Map.Entry<String, Double> entry : sortList) {
            sortedMap.put(entry.getKey(), entry.getValue());
        }

        List<String> keys = new ArrayList<>(sortedMap.keySet());
        List<String> firstFiveKeys = keys.size() > 5 ? keys.subList(0, 5) : keys;
        for(String tradeId:firstFiveKeys){
            Recommend recommend=new Recommend();
            recommend.setTradeId(tradeId);
            recommend.setUserId(BaseContext.getCurrentId());
            recommendService.save(recommend);
        }



    }



    public Double computeSimilar(String text1,String text2){
        return TextSimilarityUtil.calculateSimilarity(text1,text2);
    }

    public void matchTrade(String imageUrl,Long tradeId){


    }

    public String getTag(String base64String){

        // 使用安全认证AK/SK鉴权，替换下列示例中参数，安全认证Access Key替换your_iam_ak，Secret Key替换your_iam_sk
        Qianfan qianfan = new Qianfan(ACCESSKEY,SECRETKEY);

        // 调用大模型
        Image2TextResponse response = qianfan.image2Text().model("Fuyu-8B")
                .image(base64String)  //请替换图片的base64编码
                .prompt(PROMPT)
                .execute();

/*       ChatResponse resp = qianfan.chatCompletion()
                .model("ERNIE-Speed-Pro-128K")
                .addMessage("user", "翻译英文："+response.getResult()+"给出关键物品词")
                .execute();*/




        System.out.println(response.getResult());
        System.out.println("黑色 鼠标");

        return response.getResult();
    }

}
